package reflect应用;

/**
 * @Auther:云尚学Java
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 功能描述：
 * 相当于一个框架类ReflectFrame
 * 需求：写一个"框架"，不能改变该类的任何代码的前提下，可以帮我们创建任意类的对象，并且执行其中任意方法
 * <p>
 * 实现步骤：
    1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
    //配置文件.txt pro.properties
    //Person per = new Person();  eat  反射的中Class对象的创建.Person   eat
    //Student stu = new Student(); sleep 反射的中Class对象的创建.Student  sleep
    2. 在程序中加载读取配置文件Properties
    3. 使用反射技术来加载类文件进内存ClassLoader
    4. 创建对象newInstance();
    5. 执行方法，
    先去获取方法
    getMethod()
    invoke()执行
 */
public class ReflectFrame {
    public static void main(String[] args) throws Exception {
        //1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
        Properties pro=new Properties();
        //2. 在程序中加载读取配置文件Properties
        //依赖本地位置，根据本地路径走----不友好
        pro.load(new FileInputStream(new File("C:\\Users\\admin\\Desktop\\java-note\\java\\Java-middle\\reflect\\pro.properties")));

        //3. 使用反射技术来加载类文件进内存ClassLoader
        Class reflectFrameClass = ReflectFrame.class;
        ClassLoader classLoader = reflectFrameClass.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("resources/pro.properties");
        pro.load(is);  //加载当前这个配置文件

        /**
         * className = "reflect应用.Person.Person"
         * className = "reflect应用.Person.Student"
         *
         * methodName = sleep;
         */
        //依据什么获取什么，相当与Map集合
        String className = pro.getProperty("className");//获取全类名
        String methodName = pro.getProperty("methodName");

        System.out.println(className);
        System.out.println(methodName);

        //不能改变该类的任何代码的前提下，可以帮我们创建任意类的对象，并且执行其中任意方法
        //4. 创建对象newInstance();
        Class class1 = Class.forName(className);
        Object obj = class1.newInstance();

        //5. 执行方法，先去获取方法getMethod()  再使用invoke()执行
        //invoke()执行方法的，执行哪一个方法取决于得到的方法名称
        Method method = class1.getMethod(methodName);
        method.invoke(obj);  //执行方法

        //基于反射完成了框架的设计
        //需求：写一个"框架"，不能改变该类的任何代码的前提下，可以帮我们创建任意类的对象，并且执行其中任意方法
    }
}
